using System;
using System.Collections.Generic;
using System.Text;

namespace WOWEquipOptimizer
{
    /// <summary>
    /// OptimizerManager returns the proper Optimizer for the task at hand
    /// </summary>
    public class OptimizerManager
    {
        private Optimizer m_Optimizer;


        public Optimizer Optimizer
        {
            get
            {
                ChooseOptimizer();
                return m_Optimizer;
            }
        }
        private int m_LockCount = 0;
        private ulong m_ItemCount = 0;
        private List<Item> m_ItemList;

        public List<Item> ItemList
        {
            get { return m_ItemList; }
            set
            {
                m_ItemList = value;
                m_Items = m_Target.generateItemList(m_ItemList);
            }
        }
        private List<Item>[] m_Items;

        public List<Item>[] Items
        {
            get { return m_Items; }
            set
            {
                m_Items = value;
                FilterItemLevel();
            }
        }
        private bool[] m_Locks;

        public bool[] Locks
        {
            get { return m_Locks; }
            set { m_Locks = value; }
        }

        private Character m_Target;

        public Character Target
        {
            get { return m_Target; }
            set { m_Target = value; }
        }
        private float m_MaxTV;

        public float MaxTV
        {
            get { return m_MaxTV; }
            set { m_MaxTV = value; }
        }
        private UpdateDelegate m_UpdateGraphics;

        public UpdateDelegate UpdateGraphics
        {
            get { return m_UpdateGraphics; }
            set { m_UpdateGraphics = value; }
        }
        private int m_MinLevel = 100;

        public int MinLevel
        {
            get { return m_MinLevel; }
            set { m_MinLevel = value; }
        }

        public void EvaluateLocks()
        {
            m_LockCount = 0;
            m_ItemCount = 1;
            for (int i = 0; i < m_Locks.Length; i++)
            {
                if (m_Locks[i])
                {
                    m_LockCount++;
                }
                else
                {
                    m_ItemCount *= (ulong) m_Items[i].Count;
                }
            }
        }
        /// <summary>
        /// if everything is locked, only optimize enchants/gems
        /// if the itemcount of the non-locked slots is not that high use the partial optimizer
        /// else use full
        /// </summary>
        private void ChooseOptimizer()
        {
            EvaluateLocks();
            if (m_LockCount == m_Locks.Length)
            {
                m_Optimizer = new OptimizeAdditional();
            }
            else if (m_ItemCount < 200000 && m_LockCount > 0)
            {
                m_Optimizer = new OptimizePartial();
            }
            else
            {
                m_Optimizer = new OptimizeFull();
            }
            m_Optimizer.EnableNotification = true;
            m_Optimizer.Target = m_Target;
            m_Optimizer.Items = m_Items;
            m_Optimizer.MaxTV = m_MaxTV;
            m_Optimizer.Locks = m_Locks;
            m_Optimizer.ItemCount = m_ItemCount;
            m_Optimizer.UpdateGraphics = m_UpdateGraphics;
        }
        private void FilterItemLevel()
        {
            for (int i = 0; i < m_Items.Length; i++)
            {
                List<Item> removeme = new List<Item>();
                foreach (Item item in m_Items[i])
                {
                    if (item.Level < m_MinLevel && item.Id != Item.NoneId && item.GetType() != typeof(Gem))
                    {
                        removeme.Add(item);
                    }
                }
                foreach (Item item in removeme)
                {
                    m_Items[i].Remove(item);
                }
            }
        }
        public OptimizerManager(List<Item> items, Character target, bool[] locks, UpdateDelegate updategraphics)
        {
            m_ItemList = items;
            m_Target = target;
            m_Locks = locks;
            Items = m_Target.generateItemList(m_ItemList);
            m_UpdateGraphics = updategraphics;
        }
    }
}
